{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Experiments on multithread execution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import subprocess\n",
    "import time \n",
    "import os\n",
    "import pickle\n",
    "import multiprocessing\n",
    "from collections import namedtuple\n",
    "\n",
    "def timing_run(cmd: str, n=1, env=None):\n",
    "    assert n > 0\n",
    "    data = None\n",
    "    ts = time.time()\n",
    "    for _ in range(n):\n",
    "        cmd = cmd.split()\n",
    "        data = subprocess.run(cmd, env=env, capture_output=True)\n",
    "    te = time.time()\n",
    "    return (te - ts)/n, data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "# iteration: 0\n",
      "checking threads=1\n",
      "checking threads=2\n",
      "checking threads=3\n",
      "checking threads=4\n",
      "checking threads=5\n",
      "checking threads=6\n",
      "checking threads=7\n",
      "checking threads=8\n",
      "checking threads=9\n",
      "checking threads=10\n",
      "checking threads=11\n",
      "checking threads=12\n",
      "checking threads=13\n",
      "checking threads=14\n",
      "checking threads=15\n",
      "checking threads=16\n",
      "checking threads=17\n",
      "checking threads=18\n",
      "checking threads=19\n",
      "checking threads=20\n",
      "checking threads=21\n",
      "checking threads=22\n",
      "checking threads=23\n",
      "checking threads=24\n",
      "checking threads=25\n",
      "checking threads=26\n",
      "checking threads=27\n",
      "checking threads=28\n",
      "checking threads=29\n",
      "checking threads=30\n",
      "checking threads=31\n",
      "checking threads=32\n",
      "checking threads=33\n",
      "checking threads=34\n",
      "checking threads=35\n",
      "checking threads=36\n",
      "checking threads=37\n",
      "checking threads=38\n",
      "checking threads=39\n",
      "checking threads=40\n",
      "checking threads=41\n",
      "checking threads=42\n",
      "checking threads=43\n",
      "checking threads=44\n",
      "checking threads=45\n",
      "# iteration: 1\n",
      "checking threads=1\n",
      "checking threads=2\n",
      "checking threads=3\n",
      "checking threads=4\n",
      "checking threads=5\n",
      "checking threads=6\n",
      "checking threads=7\n",
      "checking threads=8\n",
      "checking threads=9\n",
      "checking threads=10\n",
      "checking threads=11\n",
      "checking threads=12\n",
      "checking threads=13\n",
      "checking threads=14\n",
      "checking threads=15\n",
      "checking threads=16\n",
      "checking threads=17\n",
      "checking threads=18\n",
      "checking threads=19\n",
      "checking threads=20\n",
      "checking threads=21\n",
      "checking threads=22\n",
      "checking threads=23\n",
      "checking threads=24\n",
      "checking threads=25\n",
      "checking threads=26\n",
      "checking threads=27\n",
      "checking threads=28\n",
      "checking threads=29\n",
      "checking threads=30\n",
      "checking threads=31\n",
      "checking threads=32\n",
      "checking threads=33\n",
      "checking threads=34\n",
      "checking threads=35\n",
      "checking threads=36\n",
      "checking threads=37\n",
      "checking threads=38\n",
      "checking threads=39\n",
      "checking threads=40\n",
      "checking threads=41\n",
      "checking threads=42\n",
      "checking threads=43\n",
      "checking threads=44\n",
      "checking threads=45\n",
      "# iteration: 2\n",
      "checking threads=1\n",
      "checking threads=2\n",
      "checking threads=3\n",
      "checking threads=4\n",
      "checking threads=5\n",
      "checking threads=6\n",
      "checking threads=7\n",
      "checking threads=8\n",
      "checking threads=9\n",
      "checking threads=10\n",
      "checking threads=11\n",
      "checking threads=12\n",
      "checking threads=13\n",
      "checking threads=14\n",
      "checking threads=15\n",
      "checking threads=16\n",
      "checking threads=17\n",
      "checking threads=18\n",
      "checking threads=19\n",
      "checking threads=20\n",
      "checking threads=21\n",
      "checking threads=22\n",
      "checking threads=23\n",
      "checking threads=24\n",
      "checking threads=25\n",
      "checking threads=26\n",
      "checking threads=27\n",
      "checking threads=28\n",
      "checking threads=29\n",
      "checking threads=30\n",
      "checking threads=31\n",
      "checking threads=32\n",
      "checking threads=33\n",
      "checking threads=34\n",
      "checking threads=35\n",
      "checking threads=36\n",
      "checking threads=37\n",
      "checking threads=38\n",
      "checking threads=39\n",
      "checking threads=40\n",
      "checking threads=41\n",
      "checking threads=42\n",
      "checking threads=43\n",
      "checking threads=44\n",
      "checking threads=45\n",
      "# iteration: 3\n",
      "checking threads=1\n",
      "checking threads=2\n",
      "checking threads=3\n",
      "checking threads=4\n",
      "checking threads=5\n",
      "checking threads=6\n",
      "checking threads=7\n",
      "checking threads=8\n",
      "checking threads=9\n",
      "checking threads=10\n",
      "checking threads=11\n",
      "checking threads=12\n",
      "checking threads=13\n",
      "checking threads=14\n",
      "checking threads=15\n",
      "checking threads=16\n",
      "checking threads=17\n",
      "checking threads=18\n",
      "checking threads=19\n",
      "checking threads=20\n",
      "checking threads=21\n",
      "checking threads=22\n",
      "checking threads=23\n",
      "checking threads=24\n",
      "checking threads=25\n",
      "checking threads=26\n",
      "checking threads=27\n",
      "checking threads=28\n",
      "checking threads=29\n",
      "checking threads=30\n",
      "checking threads=31\n",
      "checking threads=32\n",
      "checking threads=33\n",
      "checking threads=34\n",
      "checking threads=35\n",
      "checking threads=36\n",
      "checking threads=37\n",
      "checking threads=38\n",
      "checking threads=39\n",
      "checking threads=40\n",
      "checking threads=41\n",
      "checking threads=42\n",
      "checking threads=43\n",
      "checking threads=44\n",
      "checking threads=45\n",
      "# iteration: 4\n",
      "checking threads=1\n",
      "checking threads=2\n",
      "checking threads=3\n",
      "checking threads=4\n",
      "checking threads=5\n",
      "checking threads=6\n",
      "checking threads=7\n",
      "checking threads=8\n",
      "checking threads=9\n",
      "checking threads=10\n",
      "checking threads=11\n",
      "checking threads=12\n",
      "checking threads=13\n",
      "checking threads=14\n",
      "checking threads=15\n",
      "checking threads=16\n",
      "checking threads=17\n",
      "checking threads=18\n",
      "checking threads=19\n",
      "checking threads=20\n",
      "checking threads=21\n",
      "checking threads=22\n",
      "checking threads=23\n",
      "checking threads=24\n",
      "checking threads=25\n",
      "checking threads=26\n",
      "checking threads=27\n",
      "checking threads=28\n",
      "checking threads=29\n",
      "checking threads=30\n",
      "checking threads=31\n",
      "checking threads=32\n",
      "checking threads=33\n",
      "checking threads=34\n",
      "checking threads=35\n",
      "checking threads=36\n",
      "checking threads=37\n",
      "checking threads=38\n",
      "checking threads=39\n",
      "checking threads=40\n",
      "checking threads=41\n",
      "checking threads=42\n",
      "checking threads=43\n",
      "checking threads=44\n",
      "checking threads=45\n",
      "# iteration: 5\n",
      "checking threads=1\n",
      "checking threads=2\n",
      "checking threads=3\n",
      "checking threads=4\n",
      "checking threads=5\n",
      "checking threads=6\n",
      "checking threads=7\n",
      "checking threads=8\n",
      "checking threads=9\n",
      "checking threads=10\n",
      "checking threads=11\n",
      "checking threads=12\n",
      "checking threads=13\n",
      "checking threads=14\n",
      "checking threads=15\n",
      "checking threads=16\n",
      "checking threads=17\n",
      "checking threads=18\n",
      "checking threads=19\n",
      "checking threads=20\n",
      "checking threads=21\n",
      "checking threads=22\n",
      "checking threads=23\n",
      "checking threads=24\n",
      "checking threads=25\n",
      "checking threads=26\n",
      "checking threads=27\n",
      "checking threads=28\n",
      "checking threads=29\n",
      "checking threads=30\n",
      "checking threads=31\n",
      "checking threads=32\n",
      "checking threads=33\n",
      "checking threads=34\n",
      "checking threads=35\n",
      "checking threads=36\n",
      "checking threads=37\n",
      "checking threads=38\n",
      "checking threads=39\n",
      "checking threads=40\n",
      "checking threads=41\n",
      "checking threads=42\n",
      "checking threads=43\n",
      "checking threads=44\n",
      "checking threads=45\n",
      "# iteration: 6\n",
      "checking threads=1\n",
      "checking threads=2\n",
      "checking threads=3\n",
      "checking threads=4\n",
      "checking threads=5\n",
      "checking threads=6\n",
      "checking threads=7\n",
      "checking threads=8\n",
      "checking threads=9\n",
      "checking threads=10\n",
      "checking threads=11\n",
      "checking threads=12\n",
      "checking threads=13\n",
      "checking threads=14\n",
      "checking threads=15\n",
      "checking threads=16\n",
      "checking threads=17\n",
      "checking threads=18\n",
      "checking threads=19\n",
      "checking threads=20\n",
      "checking threads=21\n",
      "checking threads=22\n",
      "checking threads=23\n",
      "checking threads=24\n",
      "checking threads=25\n",
      "checking threads=26\n",
      "checking threads=27\n",
      "checking threads=28\n",
      "checking threads=29\n",
      "checking threads=30\n",
      "checking threads=31\n",
      "checking threads=32\n",
      "checking threads=33\n",
      "checking threads=34\n",
      "checking threads=35\n",
      "checking threads=36\n",
      "checking threads=37\n",
      "checking threads=38\n",
      "checking threads=39\n",
      "checking threads=40\n",
      "checking threads=41\n",
      "checking threads=42\n",
      "checking threads=43\n",
      "checking threads=44\n",
      "checking threads=45\n",
      "# iteration: 7\n",
      "checking threads=1\n",
      "checking threads=2\n",
      "checking threads=3\n",
      "checking threads=4\n",
      "checking threads=5\n",
      "checking threads=6\n",
      "checking threads=7\n",
      "checking threads=8\n",
      "checking threads=9\n",
      "checking threads=10\n",
      "checking threads=11\n",
      "checking threads=12\n",
      "checking threads=13\n",
      "checking threads=14\n",
      "checking threads=15\n",
      "checking threads=16\n",
      "checking threads=17\n",
      "checking threads=18\n",
      "checking threads=19\n",
      "checking threads=20\n",
      "checking threads=21\n",
      "checking threads=22\n",
      "checking threads=23\n",
      "checking threads=24\n",
      "checking threads=25\n",
      "checking threads=26\n",
      "checking threads=27\n",
      "checking threads=28\n",
      "checking threads=29\n",
      "checking threads=30\n",
      "checking threads=31\n",
      "checking threads=32\n",
      "checking threads=33\n",
      "checking threads=34\n",
      "checking threads=35\n",
      "checking threads=36\n",
      "checking threads=37\n",
      "checking threads=38\n",
      "checking threads=39\n",
      "checking threads=40\n",
      "checking threads=41\n",
      "checking threads=42\n",
      "checking threads=43\n",
      "checking threads=44\n",
      "checking threads=45\n",
      "# iteration: 8\n",
      "checking threads=1\n",
      "checking threads=2\n",
      "checking threads=3\n",
      "checking threads=4\n",
      "checking threads=5\n",
      "checking threads=6\n",
      "checking threads=7\n",
      "checking threads=8\n",
      "checking threads=9\n",
      "checking threads=10\n",
      "checking threads=11\n",
      "checking threads=12\n",
      "checking threads=13\n",
      "checking threads=14\n",
      "checking threads=15\n",
      "checking threads=16\n",
      "checking threads=17\n",
      "checking threads=18\n",
      "checking threads=19\n",
      "checking threads=20\n",
      "checking threads=21\n",
      "checking threads=22\n",
      "checking threads=23\n",
      "checking threads=24\n",
      "checking threads=25\n",
      "checking threads=26\n",
      "checking threads=27\n",
      "checking threads=28\n",
      "checking threads=29\n",
      "checking threads=30\n",
      "checking threads=31\n",
      "checking threads=32\n",
      "checking threads=33\n",
      "checking threads=34\n",
      "checking threads=35\n",
      "checking threads=36\n",
      "checking threads=37\n",
      "checking threads=38\n",
      "checking threads=39\n",
      "checking threads=40\n",
      "checking threads=41\n",
      "checking threads=42\n",
      "checking threads=43\n",
      "checking threads=44\n",
      "checking threads=45\n",
      "# iteration: 9\n",
      "checking threads=1\n",
      "checking threads=2\n",
      "checking threads=3\n",
      "checking threads=4\n",
      "checking threads=5\n",
      "checking threads=6\n",
      "checking threads=7\n",
      "checking threads=8\n",
      "checking threads=9\n",
      "checking threads=10\n",
      "checking threads=11\n",
      "checking threads=12\n",
      "checking threads=13\n",
      "checking threads=14\n",
      "checking threads=15\n",
      "checking threads=16\n",
      "checking threads=17\n",
      "checking threads=18\n",
      "checking threads=19\n",
      "checking threads=20\n",
      "checking threads=21\n",
      "checking threads=22\n",
      "checking threads=23\n",
      "checking threads=24\n",
      "checking threads=25\n",
      "checking threads=26\n",
      "checking threads=27\n",
      "checking threads=28\n",
      "checking threads=29\n",
      "checking threads=30\n",
      "checking threads=31\n",
      "checking threads=32\n",
      "checking threads=33\n",
      "checking threads=34\n",
      "checking threads=35\n",
      "checking threads=36\n",
      "checking threads=37\n",
      "checking threads=38\n",
      "checking threads=39\n",
      "checking threads=40\n",
      "checking threads=41\n",
      "checking threads=42\n",
      "checking threads=43\n",
      "checking threads=44\n",
      "checking threads=45\n"
     ]
    }
   ],
   "source": [
    "work_dir=\"/home/ck/raul\"\n",
    "repeat = 10\n",
    "max_threads = 45 #multiprocessing.cpu_count()//2\n",
    "Data = namedtuple(\"Data\", [\"threads\", \"timing\", \"status\"])\n",
    "\n",
    "data = []\n",
    "\n",
    "for r in range(repeat):\n",
    "    print(f\"# iteration: {r}\")\n",
    "    for threads in range(1,max_threads+1):\n",
    "        print(f\"checking threads={threads}\")\n",
    "        env = {\n",
    "            **os.environ,\n",
    "            \"OMP_NUM_THREADS\": str(threads),\n",
    "            \"RAUL_ASSETS\": f\"{work_dir}/testAssets\"\n",
    "        }\n",
    "\n",
    "        timing, result = timing_run(f\"{work_dir}/build/RaulTests --gtest_filter=TestOptimizerAdam.ToyNetTraining\", env=env)\n",
    "        data.append(Data(threads=threads, timing=timing, status=result.returncode))\n",
    "    pickle.dump(data, open(f\"timing_experiment_checkpoint_{r}.p\", \"wb\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYkAAAEcCAYAAAAydkhNAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8GearUAAAgAElEQVR4nOzdeXhU9bnA8e+ZfZ/sO/saNkWgiCIqiAuLaFW0LrhSl7rU1ttSe4u4tBVt61Wv1rqhdamtG0gEoeKGAm4FQfYlLCF7Mkkms8+ZuX9MmEskgWFJMknez/PkeZKZM+e8c5LMe87v/S1KNBqNIoQQQrRA09EBCCGESF6SJIQQQrRKkoQQQohWSZIQQgjRKkkSQgghWiVJQgghRKskSYiEfPPNN5x33nnH9NrS0lJGjhyJqqonOKqjN3HiRFatWtXRYXQpc+fO5amnnjrh2x6v9957jxtuuOGYXns8f+9djSLjJNrXyJEj49/7fD4MBgNarRaA+++/nwsvvPCo9nfNNddw4YUXctlll8Ufi0ajvPDCC/zrX/+ivLyctLQ0pk+fzh133IHBYEhov4MGDWL58uX06tXrqOLpCB6Ph/HjxzNq1Cief/75w247ceJEHnroIU477bQ2i2fu3LksXrwYgFAoRDQajZ/3RGJsyTXXXMO6detYvnw5ubm5AKxatYr//u//5qOPPjri65988kn27NnDn/70JwCmTp1KaWkpAH6/H51Oh06nA+Dmm2/mlltuOeoYO1JJSQmTJk1i48aN8fchTgw5m+1s7dq18e/b6gProYceYuXKlcyfP5/hw4dTXFzMb37zG3bs2MFf//rXE3qsjhIOh+MfBsuXL8dgMLBq1SqqqqrIzMzs0NgeeOABHnjgAeDQD+fjYbFYePrpp3nwwQePe1/vv/9+/PuWLjQOOPg8i+5JmpuSRCQS4dlnn+Wcc85h7Nix3HXXXdTV1QEQCAS45557GDt2LKNHj+aSSy6hurqaxx57jG+++YYHHniAkSNH8sADD7B7925ef/11/vSnPzFy5Eh0Oh0DBgzgySefZOXKlaxevRqAOXPmMHfuXK6//npGjhzJ1Vdfzf79+wG46qqrAJgxYwYjR45kyZIlfPnll0yYMCEe78SJE3n++eeZPn06J598Mvfeey/V1dXcdNNNjBw5kuuuu476+nogdpU3aNAgwuEwa9euZeTIkfGv4cOHM3HixCOegwP7ePPNNznrrLO49tpr47G8++67XHHFFQwaNIj33nuv2XlduHAhZ599NmPHjj0kQa5fv57LL7+c0aNHM378eB544AGCwWD8+UGDBvHaa69x7rnnMnLkSP7nf/6HvXv3csUVV3DKKadw1113Nds+EStWrGDq1KmMHj2aa665hp07dwLw/PPPc8cddzTb9qGHHuKhhx6K/3zNNddQVFTE3r17W9x3RUUFd9xxB6eeeioTJ07k73//OwCfffYZf/vb31i6dCkjR4487N1qa+f5zjvv5PTTT2fUqFFcddVVbN++Pf6aOXPm8NhjjwHE/05efPFFxo0bx/jx43n77bePaVuXy8Utt9zCKaecwiWXXMJjjz3GT37ykxbjvvrqqwEYM2YMI0eOZO3atbzzzjvNtj+a32dLf+8vvPAC06dPZ9SoUfz85z8nEAjEn3/uuecYP34848eP580332TQoEHs2bOn1fPcmUiSSBKvvPIKH374Ia+++iorV67E6XTGr0bfffddGhsb+eSTT/jyyy+5//77MZlM3H333YwePZq5c+eydu1a5s6dy+rVq8nJyWHEiBHN9p+bm8vJJ5/crD1+8eLF3HbbbXz55ZcMHjyYe+65B4DXXnsNgEWLFrF27VqmTJnSYszLly9nwYIFLFu2jI8//pjZs2fzi1/8gjVr1hCJRHjllVcOec2Bf+C1a9fy1VdfcdJJJzF16tQjnoMDvv76a5YsWcILL7wAwP79+/nqq6+YPn0606dPZ+HChfFtd+zYwf33388jjzzCypUrqauro7y8PP68RqPhN7/5DWvWrOGNN95g9erVvP76682O9/nnn/POO+/wr3/9i+eff57f/e53PProo3z66ads37692RX5kRQXF/PLX/6Se++9l9WrVzNhwgRuueUWgsEgF154IStXrqShoQGIXcG///77XHTRRfHXZ2dnM3PmTJ544olD9h2JRLj11lsZNGgQn332GS+//DIvv/wyK1euZMKECdx8881ccMEFrF279pBE2pIfnucJEyawbNkyVq9ezZAhQ+J/Ky2prq7G7Xbz2Wef8fvf/54HHnggfsFwNNs+8MADmM1mvvjiC+bPn9/sd/tDr776ajzuAxciLTme3+fSpUt5/vnnWbFiBVu3buWdd94BYkn4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6BqOWJPQarVotVoCgUB7xNPpGPVaslLMVNf5CUeiBMNSlxBCdB0JNTfNmjWLn//859x8883k5OQ0GwvQo0ePNguuM9DrNWSnmYlEo9TU+wmGI5jkhksI0UUklCQOrBvxxRdfNHu8uw+mA9AoCj2zYiOvq+p8+INhHBbJEkKIriGhJLFly5a2jqNTK8i2YtBrqK734/WFIeXIrxFCiM4g4fUkAEpLS6moqCAnJye+5rUAqzFWvK50+fBKN1ghRBeSUJKorKzkF7/4BevWrSMlJYW6ujpOOukk/vKXv3Trda4PMOq1ZKaY2VhcSyisEn5PO14AACAASURBVFYj6LSytoQQovNL6JNs3rx5DB48mK+++orPP/+cr776isLCQu677762jq9T0Os05KRZCIUjuNxBgiHp4SSE6BoSShLffvstv/71r7FYLABYLBZ+9atfsXbt2jYNrrNQFIXe2bGR11V1PgKSJIQQXURCScLpdLJz585mj+3atQuHw9EmQXVGvXLsaDUKVfU+mZ5DCNFlJFSTuOmmm7juuuu49NJLycvLo7S0lHfeeYe77rqrrePrNGwWAxlOE1V1fileCyG6jISSxMyZM+nRowdFRUVs3bqVrKws/vznPzNu3Li2jq/TMOi0ZKaa2VFSj9cfJhKNopEFiIQQnVzCXWDHjRt3XEmhuLiYOXPmUFdXR0pKCvPnz6d3797NtvnVr37F1q1b4z9v3bqVp556ikmTJh3zcdvLgeL197tqcXuDhMIRjHpZW0II0bkllCSCwSDvvvsumzdvxuv1NnvukUceSehA9913H1deeSUzZsxg0aJFzJ07l7///e+t7mvLli1ce+21nHHGGQntPxn0blrzutLllyQhhOgSEipcz5kzh5dffhmr1UrPnj2bfSWipqaGTZs2MW3aNACmTZvGpk2bqK2tbfU1b731FtOnT+9UM8/2zXWgAFX1PvxSlxBCdAEJ3UmsXLmSFStWHHNvprKyMrKzs+PLn2q1WrKysigrKyMtLe2Q7YPBIIsXL+all146puN1FIfVSKrDSJXLhycQIgNzR4ckhBDHJaEkkZubSzAYbOtY4j788EPy8vIoLCw86temp9sO+3xmpv1YwzqisBohP9PO3vIGDCbDEY/VlrEcrWSJJVnigOSJJVnigOSJJVnigK4fS0JJ4qKLLuK2225j1qxZpKen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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import seaborn as sns; sns.set()\n",
    "import matplotlib.pyplot as plt\n",
    "from matplotlib.ticker import MaxNLocator\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(data)\n",
    "df[\"timing\"] = df[\"timing\"] / df[\"timing\"].max()\n",
    "ax = sns.lineplot(x=\"threads\", y=\"timing\", data=df)\n",
    "ax.set_title(\"TestOptimizerAdam.ToyNetTraining timing\")\n",
    "ax.set_ylabel(\"Time (normalized)\")\n",
    "ax.set_xlabel(\"Threads\")\n",
    "ax.xaxis.set_major_locator(MaxNLocator(integer=True))\n",
    "fig = ax.get_figure()\n",
    "fig.savefig(\"timing_experiments.png\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
